/*************************************************
Name : QuickLeadRequest_WS
Created By : dthekumparampil
Created Date : Jan 9, 2013
Description : An Apex REST service class created to recieve the incoming request from WIU quickapp for new Lead creation or update existing account.
******************************
Modified By : dthekumparampil
Modified Date : Jan 14, 2013
Modification :  Changed the Class name from QuickLeadRequest to QuickLeadRequest_WS. 
                Modified the class to insert the lead into the database (without de-duplication checks).   
******************************
Modified By : dthekumparampil
Modified Date : Jan 16, 2013
Modification :  Implemented the full logic, with duplicate check.
                During duplicate check, if id found in Account, an opportunity is created.
                If its found in Lead, its updated and if its not found, a new lead is created.
******************************
Modified By : dthekumparampil
Modified Date : Feb 21, 2013 
Modification :  Passing additional parameter caseOrigin when calling method newOpportunityForAccount().
                Modified the return String. Now it returns the Colleague ID instead of Salesforce ID.
                
*************************************************/

@RestResource(urlMapping='/QuickLeadRequest/*')
global with sharing class QuickLeadRequest_WS {

/**
Method Name : createLeadOrUpdateAccount 
Created By : dthekumparampil
Created Date : Jan 9, 2013 
Description : Its just a dummy method which accepts input and returns a dummy account id.
Input Parameters : String FirstName,String LastName,String EmailAddress,String State,String ProgramOfInterest,String StartTerm,String Phone
Output Parameters : String newSalesforceId (accountId)
*******************************
Modified By : dthekumparampil
Modified Date : Jan 14, 2013
Modification : Modified the method to insert the lead into the database (without de-duplication checks).
*******************************
Modified By : dthekumparampil
Modified Date : Jan 16, 2013
Modification : Implemented the full logic, with duplicate check.
                During duplicate check, if id found in Account, an opportunity is created.
                If its found in Lead, its updated and if its not found, a new lead is created.
**/

    @HttpPost
    global static String createLeadOrUpdateAccount(String FirstName,String LastName,String EmailAddress,String State,String ProgramOfInterest,String StartTerm,String Phone,String LeadSource,String LeadSourceDetail,String RFISection) {
        //Added by Metasts for analysis
        System.debug('inside method........................');
        //end by Metasts
        String returnString;
        list<Lead> leadInSalesforce;
        list<Account> accountInSalesforce;
        String strInputParameters = '';
        /****Trimming all the Input strings****/
        FirstName=FirstName.trim();
        strInputParameters +=' FirstName: '+FirstName+' ';
        LastName=LastName.trim();
        strInputParameters +=' LastName: '+LastName+' ';
        EmailAddress=EmailAddress.trim();
        strInputParameters +=' EmailAddress: '+EmailAddress+' ';
        State=State.trim();
        strInputParameters +=' State: '+State+' ';
        ProgramOfInterest=ProgramOfInterest.trim();
        strInputParameters +=' ProgramOfInterest: '+ProgramOfInterest+' ';
        StartTerm=StartTerm.trim();
        strInputParameters +=' StartTerm: '+StartTerm+' ';
        Phone=Phone.trim();
        strInputParameters +=' Phone: '+Phone+' ';
        LeadSource = LeadSource.trim();
        strInputParameters +=' LeadSource: '+LeadSource+' ';
        LeadSourceDetail = LeadSourceDetail.trim();
        strInputParameters +=' LeadSourceDetail: '+LeadSourceDetail+' ';
        RFISection = RFISection.trim();
        strInputParameters +=' RFISection: '+RFISection+' ';
        //Added by Metasts for analysis
        System.debug('strInputParameters+++++++++++++++++++++++++'+strInputParameters);
        //end by Metasts
        
        if(LeadSource=='' && LeadSourceDetail=='' && RFISection ==''){
            LeadSource='INET';
            LeadSourceDetail = 'QUICKAPP';
            RFISection = 'west.edu';
        }
        
        
        String accountRecordType = Schema.Sobjecttype.Account.getRecordTypeInfosByName().get('West - Student Account').getRecordTypeId();
        String leadRecordType = Schema.Sobjecttype.Lead.getRecordTypeInfosByName().get('West - Prospective Student').getRecordTypeId();
        String opportunityRecordType = Schema.Sobjecttype.Opportunity.getRecordTypeInfosByName().get('West - Student Application').getRecordTypeId();

        /****Checking for empty strings in required fields.****/
        if(FirstName==''|| LastName==''|| EmailAddress==''|| State==''|| ProgramOfInterest==''|| StartTerm==''){
            return 'Failure: FirstName, LastName, EmailAddress, State, ProgramOfInterest, StartTerm are mandatory fields';
        }
        
        /*Formatting Phone number*/
        if(Phone.length()>0){
            DataFormatter formatter = new DataFormatter();
            Phone = formatter.phoneFormatter(Phone);
            if(Phone.contains('Failed')){
                system.debug('Phone format error: '+Phone);
                GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: Phone number format not supported',false);
                return 'Failure: Phone number format not supported';
            }
        }
        
        /****Checking if Date formatting is matching with Salesforce****/
        try{
            /***Date we get is in the format MM/YYYY, which is converted to YYYY-MM-DD for salesforce***/
            String[] splitDate = StartTerm.split('/', 0);
            StartTerm = splitDate[1].trim()+'-'+splitDate[0].trim()+'-01';//trimming is done for individual date strings
        }
        catch (Exception e){
            returnString = 'Failure: Date Format not supported.';
            GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: Date Format not supported.',false);
            return returnString;
        }
        
        /****Checking if Program Name exists in Database.****/
        Program__c programValue;
        try{
            system.debug(ProgramOfInterest );
            programValue = [select id, name from Program__C where name =: ProgramOfInterest LIMIT 1];
        }
        catch (Queryexception qE){
            System.debug('Error with Program Name '+qE.getMessage());
            returnString = 'Failure: No matching Program Of Interest in Database.';
            GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: No matching Program Of Interest in Database.',false);
            return returnString;
        }
        
        /****
        In the below code, first the duplicate is searched in account, if found, its updated, an opportunity is created and the Account id returned.
        If no Account record found, duplicate in Lead is searched, if found, its updated and the Lead id is returned.
        If no duplicates found in Lead or Account, New Lead record is created and the values are inserted.
        Duplicate matching is based on FirstName, LastName and EmailAddress.
        ****/
        
        /****Checking for duplicates in Account****/

        accountInSalesforce = [select id, FirstName, LastName, Phone, PersonEmail, Marketing_Email__pc, Other_Email_2__pc, RecordTypeId, Status__c,   
        University_Email__pc, Personal_Email__pc, Work_Email__pc, Other_Email__pc, account_id__c from Account where IsPersonAccount=true AND FirstName=:FirstName and 
        LastName=:LastName and (PersonEmail=:EmailAddress OR Marketing_Email__pc=:EmailAddress OR Other_Email_2__pc=:EmailAddress OR 
        University_Email__pc=:EmailAddress OR Personal_Email__pc=:EmailAddress OR Work_Email__pc=:EmailAddress OR Other_Email__pc=:EmailAddress) AND RecordTypeId =: accountRecordType ];

        /****If found, update existing Account record, create new opportunity with all the details and return account id. 
        New Opportunity is created only if the status of existing opportunities of the Account is either
        'Started' or 'Graduated' or 'Dropped' or 'Exited' or 'Declined' or 'No further Action'. Else a Case is created. 
        This logic is implemented in WebServicesUtil Class ****/
        if(accountInSalesforce.size()>0){
            accountInSalesforce[0].BillingState = State;
            accountInSalesforce[0].BillingCountry = 'USA';

            if(Phone.length()>0)
                accountInSalesforce[0].PersonHomePhone=Phone; 
            
            /****Adding Savepoint in case of failure****/
            Savepoint accountSavepoint = Database.setSavepoint();

            try{
            //Added by Metasts for analysis
        System.debug('before update'+accountInSalesforce[0]);
        //end by Metasts
                update accountInSalesforce[0];
                
            }
            catch(DmlException de){
                Database.rollback(accountSavepoint);
                GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: Account available in database, but unable to update  '+de.getMessage(),false);
                //return 'Failure: Account available in database, but unable to update';
                return 'Success: '+accountInSalesforce[0].account_id__c;
            }
            //Added by Metasts for analysis
        System.debug('after update'+accountInSalesforce[0]);
        //end by Metasts
                
            /*Commented based on email from Jaime
            //Calling Helper class containing new opprotunity creation method
            WebServicesUtil utility = new WebServicesUtil();
            
            Boolean opportunityCreationIsSuccess = utility.newOpportunityForAccount(accountInSalesforce[0].id, programValue.id,
            opportunityRecordType, LastName+' - '+programValue.name, 'Appointment', '', StartTerm, 'QuickApp'); 
            
            if(!opportunityCreationIsSuccess){
                Database.rollback(accountSavepoint);
                return 'Failure: Account found, but unable to create new Opportunity';
            }*/
            
            return 'Success: '+accountInSalesforce[0].account_id__c;
        }
        else{
            /****Checking for duplicates in Lead****/

            leadInSalesforce = [select id, FirstName, LastName, state, program__c, Country, Home_phone__c, phone, 
            Personal_Email__c, Email, Marketing_Email__c, Other_Email_2__c, Other_Email__c, Preferred_Email__c, RecordTypeId,
            University_Email__c, work_Email__c, lead_id__c,Lead_Source_2__c,Lead_Source_Detail_2__c,RFI_Section_2__c
            from lead where FirstName =:FirstName and LastName=:LastName and (Personal_Email__c=:EmailAddress OR Email=:EmailAddress 
            OR Marketing_Email__c=:EmailAddress OR Other_Email_2__c=:EmailAddress OR Other_Email__c=:EmailAddress OR Preferred_Email__c=:EmailAddress 
            OR University_Email__c=:EmailAddress OR work_Email__c=:EmailAddress) AND RecordTypeId =: leadRecordType AND isConverted=false];

            /****If found, update existing Lead record and return Lead id.****/
            if(leadInSalesforce.size()>0){
                leadInSalesforce[0].State = State;
                leadInSalesforce[0].Program__c = programValue.Id;
                leadInSalesforce[0].Country = 'USA';
                
                /*if(LeadSource=='INET' && LeadSourceDetail=='INET' && RFISection=='INET'){
                    if(leadInSalesforce[0].Lead_Source_2__c=='' && leadInSalesforce[0].Lead_Source_Detail_2__c=='' && leadInSalesforce[0].RFI_Section_2__c==''){
                        leadInSalesforce[0].Lead_Source_2__c = LeadSource;
                        leadInSalesforce[0].Lead_Source_Detail_2__c = LeadSourceDetail;
                        leadInSalesforce[0].RFI_Section_2__c = RFISection;  
                    }
                }else{*/
                leadInSalesforce[0].Lead_Source_2__c = LeadSource;
                leadInSalesforce[0].Lead_Source_Detail_2__c = LeadSourceDetail;
                leadInSalesforce[0].RFI_Section_2__c = RFISection;
                leadInSalesforce[0].RFI_Campaign_Code__c = LeadSourceDetail;
                //}
                
                if(Phone.length()>0){
                    leadInSalesforce[0].Home_Phone__c = Phone;
                    System.Debug('leadInSalesforce[0].Phone = '+leadInSalesforce[0].Phone+'\nPhone= '+Phone);
                }

                try{
                    leadInSalesforce[0].Anticipated_Start_Date__c = Date.valueOf(StartTerm);
                }
                catch(Exception e){
                    returnString = 'Failure: Date Format not supported.';
                    return returnString;
                }
                
                try{
                    update leadInSalesforce[0];
                }
                catch(DmlException de){
                    GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: Lead already exists in database, but unable to update  '+de.getMessage(),false);
                    //return 'Failure: Lead already exists in database, but unable to update';
                    return 'Success: '+leadInSalesforce[0].lead_id__c;
                    
                }
                return 'Success: '+leadInSalesforce[0].lead_id__c;
            }
            else{
                /****If no duplicate records exists in Account or Lead, create a new Lead record and insert in database.****/
                Lead newLead = new Lead();
                newLead.FirstName = FirstName;
                newLead.LastName = LastName;
                newLead.Personal_Email__c = EmailAddress;
                newLead.State = State;
                newLead.Program__c = programValue.Id;
                newLead.RecordTypeId = Schema.Sobjecttype.Lead.getRecordTypeInfosByName().get('West - Prospective Student').getRecordTypeId();
                newLead.Country = 'USA';
                newLead.LeadSource = LeadSource;
                newLead.lead_source_Detail__c = LeadSourceDetail;
                newLead.RFI_Section__c = RFISection;
                newLead.RFI_Campaign_Code__c = LeadSourceDetail;
                
                try{
                    newLead.Anticipated_Start_Date__c = Date.valueOf(StartTerm);
                }
                catch (Exception e){
                    returnString = 'Failure: Date Format not supported.';
                    return returnString;
                }

                if(Phone.length()>0){
                    newLead.Home_Phone__c = Phone;
                }
                
                try{
                    insert newLead;
                }
                catch (Dmlexception DmlE){
                    system.debug('DMLException while inserting');
                    returnString = 'Failure: Unable to insert new Lead '+DmlE.getMessage();
                    GeneralUtilWCM.createErrorLog('QuickLeadRequest_WS',strInputParameters,'Failure: Unable to insert new Lead '+DmlE.getMessage(),false);
                    return returnString;
                }
                newLead = [select id, lead_id__c from lead where id =: newLead.id];
                
                return 'Success: '+newLead.lead_id__c;
            }
        }
    }
}